﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ResourcesBitmap.cs" company="Jarno Burger">
//   See copyright.txt in the root of this project.
// </copyright>
// <summary>
//   Defines the ResourcesBitmap type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace WinFormAdapter.Resources
{
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;

    using GUI4UFramework.Colors;
    using GUI4UFramework.Management;

    using PixelFormat = System.Drawing.Imaging.PixelFormat;
    using Rectangle = System.Drawing.Rectangle;

    /// <summary>
    /// The resource pool containing the bitmaps.
    /// </summary>
    public class ResourcesBitmap : ResourcePool<Bitmap>
    {
        /// <summary>
        /// Creates a bitmap with the specified name and size.
        /// </summary>
        /// <param name="name">The preferred name.</param>
        /// <param name="width">The width of the image.</param>
        /// <param name="height">The height of the image.</param>
        /// <param name="color">The color of the image.</param>
        /// <returns>The resource location name with the created bitmap image.</returns>
        public string Create(string name, int width, int height, GUIColor color)
        {
            var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            var g = Graphics.FromImage(bitmap);
            g.Clear(Color.FromArgb(color.R, color.G, color.B));
            g.Dispose();

            var resourceName = UniqueNameCreator.GetUniqueName(name);
            Resources.Add(resourceName, bitmap);

            return resourceName;
        }

        /// <summary>
        /// Creates a image from specified URL and places them in the bitmap resources.
        /// </summary>
        /// <param name="preferredName">Name of the preferred.</param>
        /// <param name="imageUrl">The image URL.</param>
        /// <returns>The location where the resource can be found.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#")]
        public string CreateFromUrl(string preferredName, string imageUrl)
        {
#if DEBUG
            if (imageUrl == null)
            {
                throw new ArgumentNullException("imageUrl", @"The path can not be null , if we need to use it to make a bitmap");
            }

            if (File.Exists(imageUrl.ToString()) == false)
            {
                throw new ArgumentNullException("imageUrl", @"The path does not point to a file, we need it to point to a file.");
            }
#endif

            var bitmap = new Bitmap(imageUrl.ToString());
            var resourceName = UniqueNameCreator.GetUniqueName(preferredName);
            Resources.Add(resourceName, bitmap);

            return resourceName;
        }

        /// <summary>
        /// Updates the image at specified named location.
        /// </summary>
        /// <param name="name">The name for the location in the pool.</param>
        /// <param name="colorData">The color data to update the image.</param>
        public void Update(string name, GUIColor[] colorData)
        {
#if DEBUG
            if (colorData == null)
            {
                throw new ArgumentNullException("colorData", @"Colordata can not be null, cause we need to use it to update the resource.");
            }
#endif

            // first reverse the data
            var reverseData = new GUIColor[colorData.Count()];
            var r = colorData.Count() - 1;
            foreach (var guiColor in colorData)
            {
                reverseData[r] = guiColor;
                r--;
            }

            var bitmap = Resources[name];

            var width = bitmap.Width;
            var height = bitmap.Height;
            var pixelcount = width * height;
            var rectangle = new Rectangle(0, 0, width, height);
            var format = bitmap.PixelFormat;

            var bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadWrite, format);
            var pointer = bitmapData.Scan0;

            var pixels = new byte[pixelcount * 4]; // times 4 because R,G,B,A
            var i = 0;
            foreach (var guiColor in colorData)
            {
                pixels[i] = guiColor.B;
                i++;
                pixels[i] = guiColor.G;
                i++;
                pixels[i] = guiColor.R;
                i++;
                pixels[i] = guiColor.A;
                i++;
            }

            //// Copy data from byte array to pointer
            Marshal.Copy(pixels, 0, pointer, pixels.Length);

            // Unlock bitmap data
            bitmap.UnlockBits(bitmapData);
        }

        /// <summary>
        /// Debugs this instance. Let this class spit out debug info.
        /// </summary>
        public override void Debug()
        {
            System.Diagnostics.Debug.WriteLine("Library for Bitmaps contains : ");
            foreach (var resource in this.Resources)
            {
                var value = resource.Value;
                System.Diagnostics.Debug.WriteLine("resource " + resource.Key + " with " + value);
            }
        }
    }
}